/*
 * 
 * SFL java Trading System Enviroment
 * Copyright (C) 2005 Alberto Sfolcini <a.sfolcini@gmail.com>
 * 
 * This file is a part of sfljtse.
 * 
 * sfljtse is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * sfljtse is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */
package averages;

import averages.model.AbstractMA;
import averages.model.IMA;

/**
 * @title		: AMA       
 * @description	: It has been developed by Perry Kaufman, this indicator is an EMA 
 *                using an Efficiency Ratio to modify the smoothing constant, which 
 *                ranges from a minimum of Fast Length to a maximum of Slow Length.
 * @date		: 15-set-2005   
 * @author		: Alberto Sfolcini  <a.sfolcini@gmail.com>
 */
public class AMA extends AbstractMA implements IMA {

    private int fscPeriod = 2;
    private int sscPeriod = 30;
    
    /**
     * Constructor, using default values
     * @param value
     * @param periods
     */
    public AMA(double[] value, int periods) {
        super(value, periods);
        calc();
    }

    /**
     * Constructor 2
     * @param value
     * @param periods
     * @param fscPeriod
     * @param sscPeriod
     */
    public AMA(double[] value, int periods,int fscPeriod,int sscPeriod) {
        super(value, periods);
        this.fscPeriod = fscPeriod;
        this.sscPeriod = sscPeriod;
        calc();
    }

    
    /**
     * Calculate Adaptive moving average
     */
    //public void calc() {
 
   // } // end calc

    public double[] calc() {
            int size = value.length;
        if(periods>size) {
            for (int i=0;i<size;i++)
                ma[i] = 0.0;   
        } else {      
            
            double direction  = 0;
            double volatility = 0;
            double er         = 0;
            double fastC      = 0;
            double slowC      = 0;
            double ssc        = 0;
            double c          = 0;
            
            for (int i=periods;i<size;i++){
                direction = value[i] - value[i-periods];
                volatility = 0;
                for (int j=i-periods+1;j<i;j++)
                    volatility += Math.abs(value[j] - value[j-1]);
                    // Effeciency Ratio (ER) 
                    if (volatility!=0.0)
                        er = (double) direction / (double) volatility;
                    else
                        er = 0;
                    //  Fast Smoothing Constant (FastC) = 2/(p + 1)  ; where p = FSC Period
                    fastC = 2/(double) (fscPeriod+1);
                    //  Slow Smoothing Constant (SlowC) = 2/(q + 1)  ; where q = SSC Period
                    slowC = 2/(double) (sscPeriod+1);
                    //  Scaled Smoothing Constant (SSC) = ER(FastC - SlowC) + SlowC
                    ssc = er*(fastC - slowC) + slowC;
                    c = Math.pow(ssc,2);
                    if (i>periods)
                        ma[i] = value[i-1] + c*(value[i]-value[i-1]);
                    else
                        ma[i] = ma[i-1] + c*(value[i]-ma[i-1]);
            } // end for
        } // end if
        return ma;
    }

  
    

} // end class

